# 05shuju-字符串的使用-1定义变量
info1 = "D:\tools\noco"
info2 = r"D:\tools\noco"
info3 = "D:\\tools\\noco"
info4 = '张三说："你很厉害"'

print(info1)
print(info2)
print(info3)
print(info4)

# 05shuju-字符串的使用
# 1.通过位置（下标）找元素
# 定义变量
info = "abcdefg"
# 获取字母d
print(info[3])
print(info[-1])
# 2.通过元素找位置（下标）
# 字母e在哪个位置？
print(info.find("e"))
# 字母k在哪个位置？
print(info.find("k"))  # 如果找不到返回-1

# 字符串替换-定义字符串
info = "金三胖同志被称之为世界最成功的80后，金三胖真牛！"
# 使用字符串（替换）
info1 = info.replace("金三胖", "马赛克")
print(info1)
print(info)
# 结论：
# 字符串不可变数据类型，进行替换操作之后，原有的字符串不发生变化


# 字符串连接-定义变量
info = ['Python', 'Java', 'PHP']
num = [11, 22, 33]
# # 连接
info1 = " and ".join(info)
print(info1)
print(type(info1))
#
print("-".join(num))  # 序列中如果不是字符元素，报错TypeError: sequence item 0: expected str instance, int found
# 结论：
# 通过连接字符将列表/元组/集合对应字符元素才能连接成字符串


# 字符串的拆分-定义SQL语句变量
sql = "SelECt * from students  where id = 001;"
# # 上述SQL语句按照空格把语句中的单词拆分出来
print(sql.split())  # 结果类型是列表
# # 在上述基础上把每个单词打印出来？
for i in sql.split():  # 对应容器中元素的获取直接使用for循环即可
    print(i)

# str = [1,2,3,4,5]
# for i in str:
#     print(i)
# print(str)

# 上述SQL按照where拆分出来
print(sql.split("where"))  # 括号里面的字符叫分隔符

# 总结
# 1.通过split拆分后，结果是列表类型
# 2.如果split中不输符入分隔，默认按照空格拆分


# 字符串其他操作-去除字符串两头的空格
phone = " 13800000001   "
print(phone)
print(phone.strip())
# 2.大小写转换
# 转大写：字符串.upper()
# 转小写：字符串.lower()
# 定义SQL语句变量
sql = "SelECt * from students where id = 001;"
print(sql.upper())
# # 判断是否是查询（select是否存在）
if "select" in sql.upper():
    print("显示查询结果")
else:
    print("非查询")

# 综合案例
# 1. 用户输入手机号、密码、验证码
# 2. 手机号、密码、验证码去除两端空格
phone1 = input("请输入手机号：")
phone = phone1.strip()
password = input("请输入密码：").strip()
code = input("请输入验证码：").strip()
# 3. 判断是否为空
if phone == "":
    print("手机号不能为空")
elif password == "":
    print("密码不能为空")
elif code == "":
    print("验证码不能为空")
# 4. 判断手机号格式是否正确（类型、长度）
if phone.isdigit() and len(phone) == 11:
    print("手机号格式正确")
else:
    print("手机号格式不正确")
# 5.判断验证码
if code.lower() == "8888":
    print("验证码正确")
else:
    print("验证码不正确")
# 6.判断手机号、密码和验证码是否正确
if phone == "13488888888":
    print("1手机号正确")
    if password == "123456":
        print("2密码正确")
        if code.lower() == "8888":
            print("登录成功")
        else:
            print("验证码错误")
    else:
        print("密码与账号不匹配")
else:
    print("手机号不存在")

# 列表
# 定义空列表
list = []
# 类实例化方式定义
print(list)
list.insert(0, "python")
print(list)

list2 = ["web自动化", "接口自动化", "测试基础"]
print(list2)
# list2.insert(3,"python")
list2.insert(-1, "python")
print(list2)
list2.append("java")
print(list2)
list2.append("c")
print(list2)

# 列表元素查询
# 定义列表
name_list = ['张三', '李四', '王五']
# # 按照索引查元素
# # 查询李四
print(name_list[0])  # 张三
print(name_list[1])  # 李四
# # 查询不存在的索引
# print(name_list[4])
# # 总结：如果查询的下标（索引）不存在，则代码报错【索引超出了范围】
# # IndexError: list index out of range
#
# # 根据元素查索引
print(name_list.index("王五"))  # 下标是2

# 元素统计
# 定义列表
data_list = ['python', 'java', 'python', 'php']
# 统计python出现的次数
num = data_list.count("python")
print(num)  # 次数：2
# # 统计java出现次数
print(data_list.count("java"))  # 次数：1
print(data_list.count("C++"))  # 次数：0

# 结论：
# 统计列表元素出现的次数
# 元素不存在统计结果为0

# 末尾追加
# 定义列表
val_list = ["Web自动化", "UI自动化", "接口自动化"]
# 添加元素（末尾添加：APP自动化）
val_list.append("APP自动化")
# 查看原来列表
print(val_list)
# 增加数字元素
val_list.append(11)
print(val_list)
# 结论：
# 列表属于可变数据类型，增加元素后，原有的列表的值会发生变化
# 追加元素每次只能追加1个，而且每次追加的位置在列表的末尾

# 列表索引位置添加
# 定义列表
val_list = ["Web自动化", "UI自动化", "接口自动化"]
val_list.insert(1, "APP自动化")
# 查看原有列表
print(val_list)  # ['Web自动化', 'APP自动化', 'UI自动化', '接口自动化']
val_list.insert(6, "java")
print(val_list)  # ['Web自动化', 'APP自动化', 'UI自动化', '接口自动化', 'java']
# 结论：
# 指定的位置如果存在，按照指定位置插入元素；如果不存在，默认添加到列表的末尾

# 列表的合并
# 定义列表
info1 = [1, 2, 3]
info2 = [4, 5, 6]
# 合并
info1.extend(info2)
# info2.extend(info1)
# 查看原来列表1
print(info1)  # [1, 2, 3, 4, 5, 6]
print(info2)  # [4, 5, 6]

# 列表元素删除
# 定义列表
val_list = ['Web自动化', 'APP自动化', 'UI自动化', '接口自动化', 'java']
# 删除下标为2对应元素
val_list.pop(2)  # 删除不传入索引时，默认删除列表最后一个数据（元素）
# 查看原有列表
print(val_list)
# 下标为空删除
val_list.pop()
print(val_list)
# 删除下标为7的元素
# val_list.pop(7)  # IndexError: pop index out of range
print(val_list)
# 结论：
# 1.下标存在直接按照指定下标删除;如果下标不存在，直接报错
# 2.如果下标不写，默认删除最后一个元素

# 列表元素删除
# 定义列表
val_list = ['Web自动化', 'APP自动化', 'java', 'UI自动化', '接口自动化', 'java']
# 删除：“APP自动化”
val_list.remove('APP自动化')
# 查看原有列表
print(val_list)  # ['Web自动化', 'java', 'UI自动化', '接口自动化', 'java']
# # 删除：java
val_list.remove('java')
print(val_list)  # ['Web自动化', 'UI自动化', '接口自动化', 'java']
# 删除：python
# val_list.remove("python")  # 报错：ValueError: list.remove(x): x not in list
# 总结：
# 1. 如果元素存在直接删除，如果存在多个元素默认删除第一个匹配到的
# 2. 如果元素不不存在直接删除，报错


# 列表元素修改
# 定义列表
val_list = ["Web自动化", "UI自动化", "接口自动化", "APP自动化"]
# 把UI自动化修改为性能自动化
val_list[1] = "性能自动化"
# 查看原有列表
print(val_list)
# 指定下标为5的数据修改为：python
# val_list[5] = "python"  # IndexError: list assignment index out of range
# 结论
# 1.下标存在直接修改对应位置的元素；下标不存在直接报错


# 列表元素反转：元素倒置（反转）
# 定义列表
info = [8, 100, 30, 10, 40, 2]
# 反转
info.reverse()
# 查看原有列表
print(info)  # [2, 40, 10, 30, 100, 8]

# 列表元素排序：大小排列🏴
# 定义列表
info = [8, 100, 30, 10, 40, 2]
# 从小到大排序
info.sort()
# info.sort(reverse=False)
# 查看原有列表
print(info)
# 从大到小排序
info.sort(reverse=True)
print(info)
# 结论：
# 1.sort内部有常见两个参数，key:表示按照哪个指标排序（key的值必须是一个函数），reverse:表示排序规则（升序/降序）
# 2.reverse=False表示升序（默认可以不写）；如果reverse=True表示降序


# 表的嵌套元素获取：列表中的元素还是列表🏴
# 定义列表
# 列表中的元素还是列表：列表嵌套
student_list = [["张三", "18", "功能测试"], ["李四", "20", "自动化测试"], ["王五", "22", ["python", "java"]]]
# 获取指定的元素
# 查找元素18，如何查找？
print(student_list[0])
aa = student_list[0]  # ['张三', '18', '功能测试']
print(aa[1])  # 18
# # 合并起来
print(student_list[0][1])  # 18
# # 查找李四
print(student_list[1][0])  # 李四
# # 查找java
print(student_list[2][2][1])  # java

# 列表的嵌套：列表中的元素还是列表
# 登录页面为例
# 需求：分别使用不同的数据（包括手机号、密码、验证码）进行登录验证
# 结果：账号或密码错误；验证码错误；登录成功

# 定义非空列表(把每种测试结果的数据放在一起)
login_data = [
    ["13488888888", "666666", "8888"],
    ["13488888880", "123456", "8888"],
    ["13488888888", "123456", "0000"],
    ["13488888888", "123456", "8888"]
]
# 遍历
for i in login_data:
    # print(i) # 每一个中括号的数据 ，i = ["13488888888", "123456", "8888"]
    # 判断手机号和密码
    if i[0] == "13488888888" and i[1] == "123456":
        # 判断验证码
        if i[2] == "8888":
            print("登录成功")
        else:
            print("验证码错误")
    else:
        print("用户名或密码错误")

# 练习
list = [1, 2, 3, 4, 1, 6, 5, 61, 1, 1, 1, 1]
# while 1 in list:
#     list.remove(1)
# print(list)

for i in list:
    list.remove(1)
print(list)

# 定义空元组
info = ()
info1 = tuple()
print(info)
print(info1)
# 非空
info2 = (11, 22, 33, 44)
print(info2)
# # 单个元素
# info3 = ("55") # 不加逗号此时为：<class 'str'>
info3 = ("55",)
print(type(info3))  # <class 'tuple'>
# # 不写括号
info4 = 1, 2, 3, 4
print(type(info4))  # <class 'tuple'>
# 结论：
# 1. 元组的括号可以省略
# 2. 元组是一个元素值时，需要在元素后面加逗号


# 元组元素查询：索引
# 定义元组
info = (11, "aaa", 1.88)
# 查看下标为2对应元素
print(info[2])  # 1.88   #-1
# 查看下标为4对应元素
# print(info[4]) # IndexError: tuple index out of range
# 总结：
# 1.如果下标存在，直接查询对应位置的元素；下标不存在直接报错


# 元组元素查询：元素统计
# 定义元组
info = (1, 2, 3, 2)
# 统计元素2出现的次数
print(info.count(2))  # 出现2次
print(info.count(3))  # 出现1次
print(info.count(4))  # 出现0次

# 定义变量
num1 = 100
num2 = 200
# 交换两个数据
# 方式1：找第三个变量，进行互换
tmp = num1
num1 = num2
num2 = tmp
print("此时num1的值：", num1)
print("此时num2的值：", num2)

# 方式2：直接借助于python元组类型的数据直接替换
aa = 200  # 相当于把200给aa
bb = 100  # 相当于把100给bb
num1 = aa  # num1 = 200
num2 = bb  # num2 = 100
# 合并结果 # num1, num2 = 200, 100
num1, num2 = num2, num1  # 元组元素的外层小括号可以省略
print("此时num1的值：", num1)
print("此时num2的值：", num2)

# 定义空字典
info = {}
info1 = dict()
print(type(info), type(info1))
print(info)
# # 非空字典
info2 = {"name": "张三", "age": 22, "height": 1.88}
print(info2)
print(type(info2))
# # 结论：
# 1.键名不能重复
# 2.键的数据类型可以任意（推荐用字符串）

# 字典新增或修改值
# 定义非空字典
info = {"name": "张三"}
# 将张三修改为李四
info["name"] = "李四"
# 查看原有字典
print(info)  # {'name': '李四'}
# 增加年龄为22岁
info["age"] = 22
# # 查看原有字典
print(info)  # {'name': '李四', 'age': 22}
# 结论：
# 1.字典中键存在修改值，不存在新增键和值


# 字典删除值
info = {'name': '李四', 'age': 22}
# 删除年龄22
info.pop("age")
# 查看原来字典
print(info)
# 删除性别
# info.pop("sex") # KeyError: 'sex'
# 结论：
# 1.键存在直接删除对应键和值，键不存在报错


# 定义非空字典
info = {
    "name": "tom",
    "age": 18,
    "gender": "男",
    "hobby": {"read": "小说", "sport": ["篮球", "足球"]}
}

# 查询年龄
a1 = info["age"]  # 格式1   变量 = 字典名[键]
print(a1)
print(info["age"])
a2 = info.get("age")  # 格式2  变量 = 字典名.get(键)
print(a2)
print(info.get("age"))
# # 查询键aa的值
# print(info["aa"])  # 代码报错：KeyError: 'aa'  键aa不存在
print(info.get("aa"))  # None 表示aa键不存在
# # 思考：如何获取值："足球"
a1 = info["hobby"]
print(a1)  # {'read': '小说', 'sport': ['篮球', '足球']}
print(a1["sport"])  # ['篮球', '足球']
print(a1["sport"][1])
# # 组合:从外部一层一层获取递进
print(info["hobby"]["sport"][1])
print(info.get("hobby").get("sport")[1])

# 结论：
# 1.键存在，两个方法无区别，如果键不存在，get方法直接返回None，但是通过键直接查询会报错


# 字典的合并/新增
# 定义字典1
dict1 = {"name": "张三", "age": 18}
# 定义字典2
dict2 = {"height": 1.88}
# 将字典2合并到字典1
dict1.update(dict2)
print(dict1)

# 定义非空字典
info = {
    "name": "tom",
    "age": 18,
    "gender": "男"
}
# 遍历获取字典中所有键
for i in info.keys():
    print(f"字典的键是：{i}")
# 遍历获取字典中所有值
for i in info.values():
    print(f"字典的值是：{i}")
# 遍历获取字典的键和值
for k, v in info.items():
    print(f"{k} = {v}")

# 1.定义空集合
info = set()
print(info)
# 2.集合中添加元素："a"
info.add(1)
info.add("b")
print(info)

# 定义非空字符串
var = "abcdeabdcdf"
# 3.打印非重复的元素
print(set(var))  # 转换为集合去重 # {'c', 'f', 'e', 'a', 'b', 'd'}
tmp = list(set(var))  # 再转换为列表
tmp.sort()  # 再进行排序
# tmp.sort(reverse=True)  # 再进行排序
print(tmp)  # ['a', 'b', 'c', 'd', 'e', 'f']
print("".join(tmp))  # 还原成字符串：abcdef

# 语法格式：变量名[start:end:step]
# - start：切片开始下标
# - end：切片结束下标
# - step：切片步长【可选】
# 步长值默认为1

# 作用：按照指定要求获取一段数据
# 定义非空字符串
name = "abcdefgh"
# 获取cde
print(name[2:5])
print(name[2:5:1])
print(name[-6:-3])
print(name[-6:-3:1])
# 获取defgh的字符
print(name[3:8])
print(name[3:])  # 结束下标不写，默认从开始下标到结尾
print(name[-5:])
# 获取abc的字符

# 获取ace的字符
print(name[0:5:2])  # 取出0 、2 、4下标对应元素
print(name[:5:2])  # 开始下标不写，默认从第一个元素开始

# 获取hgfedcba
print(name[::-1])

# 定义非空字符串
info = "abcdefgh"
info1 = "Hello Python"
# 统计字符元素个数（长度）
print(len(info))  # 8
print(len(info1))  # 12
# 定义非空列表
info2 = [11, "aa", 1.88, (1, 2, 3), ["aa", "bb"]]
print(len(info2))  # 5
# # 定义非空元组
info3 = (11, "aa", 1.88)
print(len(info3))  # 3
# # 定义非空字典
info4 = {"name": "tom", "age": 18, "gender": "男"}
print(len(info4))  # 3
# # 结论：
# 1.字典元素统计按照键值对统计


info2 = [11, "aa", 1.88, (1, 2, 3), ["aa", "bb"]]
# 清空列表数据
info2.clear()
# 查看原有列表
print(info2)

info4 = {"name": "tom", "age": 18, "gender": "男"}
# 清空字典数据
info4.clear()
# 查看原有字典
print(info4)
# 结论：只针对可变数据类型可以做清空


# 综合案例
"""
案例需求：
参考项目的登录功能（登录时需要输入用户名、密码、验证码），至少设计3条测试用例
要求1：定义变量保存测试数据（包括不同测试数据对应的测试结果）
要求2：至少写出3种以上不同的数据格式
要求3：遍历测试数据并打印到控制台，数据格式“用户名：xxx 密码：xxx 验证码：xxx 期望结果：xxx”
"""

# 分析：①登录成功②用户名或密码错误③验证码错误
# 测试数据：
# 1.请求：用户名、密码、验证码
# 2.响应：预期结果
# 组装数据：每一种结果对应的场景放到一个序列里面

# 案例：记录登录功能测试用例数据
# 思考：测试用例？ 登录成功、用户名或密码错误、验证码错误
# 存放的数据：用户名、密码、验证码、预期结果

# 定义变量：列表
login_data1 = [
    ["13800000001", "123456", "8888", "登录成功"],
    ["13800000001", "1234", "8888", "密码错误"],
    ["13800000001", "123456", "0000", "验证码错误"]
]
# 定义变量：元组
login_data2 = (
    ("13800000001", "123456", "8888", "登录成功"),
    ("13800000001", "1234", "8888", "密码错误"),
    ("13800000001", "123456", "0000", "验证码错误")
)
# 定义变量：列表元组
login_data3 = [
    ("13800000001", "123456", "8888", "登录成功"),
    ("13800000001", "1234", "8888", "密码错误"),
    ("13800000001", "123456", "0000", "验证码错误")
]
# 定义变量：列表字典
login_data4 = [
    {"username": "13800000001", "password": "123456", "code": "8888", "result": "登录成功"},
    {"username": "13800000001", "password": "666666", "code": "8888", "result": "密码错误"},
    {"username": "13800000001", "password": "123456", "code": "0000", "result": "验证码错误"}
]

# 遍历数据3
for i in login_data3:
    # print(i)
    print(f"用户名：{i[0]} 密码：{i[1]} 验证码：{i[2]} 期望结果：{i[3]}")

# 遍历数据4
for i in login_data4:
    # print(i)
    print(f"用户名：{i.get('username')} 密码：{i.get('password')} "
          f"验证码：{i.get('code')} 期望结果：{i.get('result')}")
    # print(f"用户名：{i['username']}")

# 遍历数据1
for i in login_data1:
    print(f"用户名：{i[0]} 密码：{i[1]} 验证码：{i[2]} 期望结果：{i[3]}")

# 遍历数据2
for i in login_data2:
    print(f"用户名：{i[0]} 密码：{i[1]} 验证码：{i[2]} 期望结果：{i[3]}")
